home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
AMIGA
/
AMICUS
/
AMICUS12.ADF
/
C
/
Spin3.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-08-05
|
16KB
|
506 lines
/* ---------------------------- S p i n 3 . c ------------------------------ */
/* This is a simple routine that creates some spinning cubes and transforms */
/* them into op-art. It is a good example of how to take total control of */
/* of the screen for graphics and create a double buffered display (with */
/* color tables that can be changed!) */
/* I place it in the public domain so long as no one uses it for profit and */
/* these comments remain with the source code. */
/* Ronald Peterson PeopleLink: OPS448 BIX: rpeterson */
/*---------------------------------------------------------------------------*/
/*--- INCLUDE's ------------------------------------------------------------ */
#include "stdio.h"
#include "math.h"
#include "limits.h"
#include "exec/types.h"
#include "graphics/gfx.h"
#include "graphics/gfxmacros.h"
#include "graphics/copper.h"
#include "graphics/view.h"
#include "graphics/regions.h"
#include "graphics/clip.h"
#include "exec/exec.h"
#include "graphics/gfxbase.h"
#include "graphics/rastport.h"
#include "hardware/custom.h"
#include "hardware/dmabits.h"
/*--- DEFINE's --------------------------------------------------------------*/
#define DEPTH 4
#define COLORS 16 /* COLORS = 2**DEPTH */
#define WIDTH 320
#define HEIGHT 200
#define NOT_ENOUGH_MEMORY -1000
/*--- GLOBAL variable definitions -------------------------------------------*/
struct View v;
struct ViewPort vp;
struct ColorMap *cm; /* pointer to colormap structure, dynamic alloc */
struct RasInfo ri;
struct BitMap b; /* note: Due to the static allocation of a structure
* accessed directly by the custom chips, this program
* will only work if it resides entirely within the lower
* 512k bytes of memory (CHIP memory)
*/
struct BitMap b2; /* second bitmap for double buffering */
struct cprlist *lof1; /* copper list pointers for double buffer */
struct cprlist *lof2;
struct cprlist *shf1;
struct cprlist *shf2;
struct CopList *Disp1, *Disp2;
extern int Enable_Abort;
/*--- RastPort variables ----------------- */
PLANEPTR rastpoint, rastpoint2;
struct RastPort rp;
struct RastPort rp2;
WORD areabuffer[250];
struct TmpRas tmpras;
struct AreaInfo myAreaInfo;
WORD areabuffer2[250];
struct TmpRas tmpras2;
struct AreaInfo myAreaInfo2;
/*--- My global variables */
extern struct Custom custom; /* so that graphics macros work. OFF_SPRITE */
extern struct ColorMap *GetColorMap();
struct GfxBase *GfxBase;
struct View *oldview; /* save pointer to old view so can restore */
USHORT colortable[COLORS] = {0x0000, 0x0222,
0x0444, 0x0555, 0x0666, 0x0777, 0x0888, 0x0999, 0x0AAA, 0x0BBB, 0x0CCC,
0x0DDD, 0x0EEE, 0x0FFF, 0x0005, 0x000A};
/* set colors shades of white, Light blue, Medium blue */
/* 0-13 14 15 */
USHORT j, tmp;
UBYTE *displaymem;
UWORD *colorpalette;
/*--- Start of main routine -------------------------------------------------*/
main()
{
SHORT bx[30], by[30], bz[30], dx[30], dy[30], dz[30];
SHORT size[30], xminus, xplus, yminus, yplus;
SHORT cx, cy, cz, half, nobj;
LONG i;
SHORT k, icol[30], icol2, xhalf, dxhalf, ncol;
static SHORT icl[8] = {256, 16, 1, 4096, -256, -16, -1 ,-4096};
static float scl[7] = {1.0, 1.138, 1.276, 1.414, 1.276, 1.138, 1.0};
/*--- Open graphics and Intuition libraries */
GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0);
if(GfxBase == NULL)exit(1);
oldview = GfxBase->ActiView; /* Save current view to restore later */
/* Steals screen from Intuition if */
/* started from WorkBench. */
/*--- Initialize graphics structures and create double buffered display. */
OFF_SPRITE; /* turn off pointer (sprites off) */
InitView(&v); /* initialize view */
InitVPort(&vp); /* initialize viewport */
v.ViewPort = &vp; /* link view into viewport */
InitBitMap(&b,DEPTH,WIDTH,HEIGHT); /* Init two bitmaps for double */
InitBitMap(&b2,DEPTH,WIDTH,HEIGHT); /* buffering (for RasInfo & RastPort) */
ri.BitMap = &b; /* Init RasInfo structure */
ri.RxOffset = 0;
ri.RyOffset = 0;
ri.Next = NULL;
vp.DWidth = WIDTH; /* Specify ViewPort characteristics. */
vp.DHeight = HEIGHT;
vp.RasInfo = &ri;
cm = GetColorMap(COLORS); /* Init color table (16 slots since 4 planes deep */
vp.ColorMap = cm; /* Set ViewPort pointer to my colors */
LoadRGB4(&vp,colortable,COLORS); /* Set viewport colors */
for(i=0; i<DEPTH; i++) /* Allocate RAM for bitmaps. */
{
b.Planes[i] = (PLANEPTR)AllocRaster(WIDTH,HEIGHT);
if(b.Planes[i] == NULL)exit(NOT_ENOUGH_MEMORY);
b2.Planes[i] = (PLANEPTR)AllocRaster(WIDTH,HEIGHT);
if(b2.Planes[i] == NULL)exit(NOT_ENOUGH_MEMORY);
}
ri.BitMap = &b;
MakeVPort(&v,&vp); /* construct copper instr (prelim) list */
MrgCop(&v); /* merge prelim lists together into a real */
/* copper list in the view structure */
lof1 = v.LOFCprList; /* store pointers to copper lists for bitmap 1 */
shf1 = v.SHFCprList;
Disp1 = v.ViewPort->DspIns; /* To get color map to change properly */
v.LOFCprList = 0;
v.SHFCprList = 0;
v.ViewPort->DspIns = 0;
ri.BitMap = &b2;
MakeVPort(&v,&vp);
MrgCop(&v);
lof2 = v.LOFCprList; /* store pointers to copper lists for bitmap 2 */
shf2 = v.SHFCprList;
Disp2 = v.ViewPort->DspIns;
LoadView(&v); /* tell copper to use list for display */
InitRastPort(&rp); /* Initialize first RastPort */
rp.BitMap = &b; /* link rastport to bitmap 1 */
SetDrMd(&rp,JAM1); /* set draw mode to JAM1 */
InitArea(&myAreaInfo, areabuffer, 100); /* Vertice buffer for Fill */
rp.AreaInfo = &myAreaInfo;
rastpoint = (PLANEPTR)AllocRaster(WIDTH,HEIGHT);
InitTmpRas(&tmpras, rastpoint, RASSIZE(WIDTH,HEIGHT));
rp.TmpRas = &tmpras;
InitRastPort(&rp2); /* Do same for second RastPort */
rp2.BitMap = &b2; /* link rastport to bitmap */
SetDrMd(&rp2,JAM1); /* set draw mode to JAM1 */
InitArea(&myAreaInfo2, areabuffer2, 100); /* Vertice buffer for Fill */
rp2.AreaInfo = &myAreaInfo2;
rastpoint2 = (PLANEPTR)AllocRaster(WIDTH,HEIGHT);
InitTmpRas(&tmpras2, rastpoint2, RASSIZE(WIDTH,HEIGHT));
rp2.TmpRas = &tmpras2;
/*--- Set outline colors and clear bitmaps. */
SetOPen(&rp,0); /* set outline color */
SetOPen(&rp2,0); /* set outline color */
Enable_Abort = 0; /* disable automatic CTRL-C abort */
SetRast(&rp2,0); /* clear bitmap 2 */
SetRast(&rp,0); /* clear bitmap 1 */
/*--- Set up positions, sizes, and directions for balls. */
for(i=0; i<30; i++)
{
bx[i] = RangeRand(239) + 40; /* pick an initial location inside */
by[i] = RangeRand(119) + 40; /* the clipping range. */
bz[i] = RangeRand(239) + 40;
dx[i] = RangeRand(30) - 15;
dy[i] = RangeRand(30) - 15;
dz[i] = RangeRand(30) - 15;
if(dx[i] == 0)dx[i] = 10; /* zero dx not allowed */
if(dy[i] == 0)dy[i] = 10;
if(dz[i] == 0)dz[i] = 10;
size[i] = (319-bz[i])/12+ 1; /* ball size is a function of z */
}
for(k=0; k<30; k++) /* Initialize cube parameters */
{
icol[k] = RangeRand(6) + 7;
}
/*--- Swap buffers, alternately drawing into each */
ncol = 0;
nobj = 3;
for(i=0; i<100000; i++)
{
if(0 != Chk_Abort()) /* check for CTRL-C abort */
{
goto dats_all;
}
v.LOFCprList = lof1; /* set pointers to copper lists and */
v.SHFCprList = shf1; /* set RastPort bitmap pointer */
v.ViewPort->DspIns = Disp1;
WaitBOVP(&vp); /* wait till in vertical blank area */
LoadView(&v); /* display bitmap 1 */
if(i < 100)SetRast(&rp2,0); /* clear bitmap 2 */
if(i > 250)
{
tmp = colortable[0]; /* rotate colors */
for(j=0; j<15; j++)
{
colortable[j] = colortable[j+1];
}
colortable[15] = tmp;
}
if(i > 200)ncol = RangeRand(15);
colortable[ncol] = (colortable[ncol] + icl[RangeRand(8)]) & 0x0FFF;
if(i > 150)LoadRGB4(&vp,colortable,COLORS); /* Set viewport colors */
if(i < 200)
{
SetAPen(&rp2,14); /* Set wall color */
AreaMove(&rp2, 0, 0);
AreaDraw(&rp2, 0, 199);
AreaDraw(&rp2, 80, 150);
AreaDraw(&rp2, 80, 50);
AreaEnd(&rp2);
SetAPen(&rp2,11); /* Set wall color */
AreaMove(&rp2, 319, 0);
AreaDraw(&rp2, 319, 199);
AreaDraw(&rp2, 240, 150);
AreaDraw(&rp2, 240, 50);
AreaEnd(&rp2);
SetAPen(&rp2,15); /* Set floor/ceiling color */
AreaMove(&rp2, 0, 0);
AreaDraw(&rp2, 80, 50);
AreaDraw(&rp2, 240, 50);
AreaDraw(&rp2, 319, 0);
AreaMove(&rp2, 0, 199);
AreaDraw(&rp2, 80, 150);
AreaDraw(&rp2, 240, 150);
AreaDraw(&rp2, 319, 199);
AreaEnd(&rp2);
}
/* if(i < 150) /* start with one object, then go to three */
nobj = 3;
else
nobj = 10;
*/
for(k=0; k<nobj; k++) /* move and draw balls */
{
bx[k] = bx[k] + dx[k]; /* increment positions. */
by[k] = by[k] + dy[k];
bz[k] = bz[k] + dz[k];
size[k] = (319-bz[k])/12 + 1;
if(bx[k]+size[k] > 319) /* clip & change direction. */
{
bx[k] = 319 - size[k];
dx[k] = RangeRand(10) - 11; /* set negative dx */
}
if(by[k]+size[k] > 199)
{
by[k] = 199 - size[k];
dy[k] = RangeRand(10) - 11;
}
if(bz[k] > 319)
{
bz[k] = 319;
dz[k] = RangeRand(10) - 11;
}
if(bx[k]-size[k] < 0)
{
bx[k] = size[k];
dx[k] = RangeRand(10) + 1; /* set positive dx */
}
if(by[k]-size[k] < 0)
{
by[k] = size[k];
dy[k] = RangeRand(10) + 1;
}
if(bz[k] < 20)
{
bz[k] = 20;
dz[k] = RangeRand(10) + 1;
}
cx = bx[k];
cy = by[k];
cz = bz[k];
perspective(&cx, &cy, &cz); /* do perspective xform */
half = size[k]/2;
icol[k] = icol[k] - 1;
if(icol[k] < 7)icol[k] = 13;
icol2 = icol[k] - 7;
dxhalf = scl[icol2]*half;
xhalf = cx - dxhalf + icol2*dxhalf/3;
xminus = cx-dxhalf;
xplus = cx+dxhalf;
yminus = cy-half;
yplus = cy+half;
SetAPen(&rp2,icol2); /* Set color to show rotation */
AreaMove(&rp2, xminus, yminus);
AreaDraw(&rp2, xhalf, yminus);
AreaDraw(&rp2, xhalf, yplus);
AreaDraw(&rp2, xminus, yplus);
AreaEnd(&rp2);
SetAPen(&rp2,icol[k]); /* Set color to show rotation */
AreaMove(&rp2, xhalf, yminus);
AreaDraw(&rp2, xplus, yminus);
AreaDraw(&rp2, xplus, yplus);
AreaDraw(&rp2, xhalf, yplus);
AreaEnd(&rp2);
}
v.LOFCprList = lof2; /* set pointers to copper lists and */
v.SHFCprList = shf2; /* set RastPort bitmap pointer */
v.ViewPort->DspIns = Disp2;
WaitBOVP(&vp); /* wait till in vertical blank area */
LoadView(&v); /* display bitmap 2 */
if(i < 100)SetRast(&rp,0); /* clear bitmap 1 */
if(i > 150)LoadRGB4(&vp,colortable,COLORS); /* Set viewport colors */
if(i < 200)
{
SetAPen(&rp,14); /* Set wall color */
AreaMove(&rp, 0, 0);
AreaDraw(&rp, 0, 199);
AreaDraw(&rp, 80, 150);
AreaDraw(&rp, 80, 50);
AreaEnd(&rp);
SetAPen(&rp,11); /* Set wall color */
AreaMove(&rp, 319, 0);
AreaDraw(&rp, 319, 199);
AreaDraw(&rp, 240, 150);
AreaDraw(&rp, 240, 50);
AreaEnd(&rp);
SetAPen(&rp,15); /* Set floor color */
AreaMove(&rp, 0, 0);
AreaDraw(&rp, 80, 50);
AreaDraw(&rp, 240, 50);
AreaDraw(&rp, 319, 0);
AreaMove(&rp, 0, 199);
AreaDraw(&rp, 80, 150);
AreaDraw(&rp, 240, 150);
AreaDraw(&rp, 319, 199);
AreaEnd(&rp);
}
for(k=0; k<nobj; k++) /* draw a boxes spinning and others */
{
bx[k] = bx[k] + dx[k]; /* increment positions. */
by[k] = by[k] + dy[k];
bz[k] = bz[k] + dz[k];
size[k] = (319-bz[k])/12 + 1;
if(bx[k]+size[k] > 319) /* clip & change direction. */
{
bx[k] = 319 - size[k];
dx[k] = RangeRand(10) - 11; /* set negative dx */
}
if(by[k]+size[k] > 199)
{
by[k] = 199 - size[k];
dy[k] = RangeRand(10) - 11;
}
if(bz[k] > 319)
{
bz[k] = 319;
dz[k] = RangeRand(10) - 11;
}
if(bx[k]-size[k] < 0)
{
bx[k] = size[k];
dx[k] = RangeRand(10) + 1; /* set positive dx */
}
if(by[k]-size[k] < 0)
{
by[k] = size[k];
dy[k] = RangeRand(10) + 1;
}
if(bz[k] < 20)
{
bz[k] = 20;
dz[k] = RangeRand(10) + 1;
}
cx = bx[k];
cy = by[k];
cz = bz[k];
perspective(&cx, &cy, &cz); /* do perspective xform */
half = size[k]/2;
icol[k] = icol[k] - 1;
if(icol[k] < 7)icol[k] = 13;
icol2 = icol[k] - 7;
dxhalf = scl[icol2]*half;
xhalf = cx - dxhalf + icol2*dxhalf/3;
xminus = cx-dxhalf;
xplus = cx+dxhalf;
yminus = cy-half;
yplus = cy+half;
SetAPen(&rp,icol2); /* Set color to show rotation */
AreaMove(&rp, xminus, yminus);
AreaDraw(&rp, xhalf, yminus);
AreaDraw(&rp, xhalf, yplus);
AreaDraw(&rp, xminus, yplus);
AreaEnd(&rp);
SetAPen(&rp,icol[k]); /* Set color to show rotation */
AreaMove(&rp, xhalf, yminus);
AreaDraw(&rp, xplus, yminus);
AreaDraw(&rp, xplus, yplus);
AreaDraw(&rp, xhalf, yplus);
AreaEnd(&rp);
}
}
dats_all:
ON_SPRITE; /* turn on pointer (sprites on) */
LoadView(oldview); /* put back the old view */
FreeMemory(); /* exit gracefully */
CloseLibrary(GfxBase); /* since opened library, close it */
}
/* End of main ----------------------------------------------------------*/
/* return user and system-allocated memory to sys manager */
FreeMemory()
{
int i;
FreeRaster(rastpoint,WIDTH,HEIGHT); /* Free drawing areas */
FreeRaster(rastpoint2,WIDTH,HEIGHT);
for(i=0; i<DEPTH; i++) /* Free bitmap RAM */
{
FreeRaster(b.Planes[i],WIDTH,HEIGHT);
FreeRaster(b2.Planes[i],WIDTH,HEIGHT);
}
FreeColorMap(cm); /* Free colormap */
v.LOFCprList = lof1; /* Free Copper structures */
v.SHFCprList = shf1;
FreeVPortCopLists(&vp);
FreeCprList(v.LOFCprList);
FreeCprList(v.SHFCprList); /* Free interlace copper lists */
v.LOFCprList = lof2;
v.SHFCprList = shf2;
FreeVPortCopLists(&vp);
FreeCprList(v.LOFCprList);
FreeCprList(v.SHFCprList);
return(0);
}
int perspective(x, y, z)
SHORT *x, *y, *z;
{
static float eye_x = 160., eye_y = 100., eye_z = -320.; /* set viewpoint */
static float range, sclx = 319., scly = 319.; /* set scale factor */
range = *z - eye_z;
if(range != 0)
{
*x = (SHORT)(eye_x + sclx * ((float)*x-eye_x)/range);
*y = (SHORT)(eye_y + scly * ((float)*y-eye_y)/range);
/* *z = (SHORT)(1. * (float)*z); */
}
}